package descentFly.away3D4.Generator
{
	import UIFree.ObjectEvent;
	
	import away3d.entities.Mesh;
	
	import descentFly.away3D4.df_awaySpace;
	import descentFly.away3D4.df_baseSpaceElement;
	import descentFly.away3D4.element.df_element;
	import descentFly.away3D4.net.df_netSupport;
	import descentFly.df_spaceObject;
	
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	public class df_pointsGenerator extends df_basePoints {
		private var _curPoint	: int;
		private var _timer		: Timer;
		private var _netSession	: Boolean;
		
		public function df_pointsGenerator(a_space:df_awaySpace, a_options:Object) {
			super(a_space, a_options);
			_netSession	= false;
			_timer 		= df_spaceObject.createTimer(options.period, doPeriod);
			_curPoint 	= 0;
			_timer.start();
			Space.view.stage.addEventListener(df_netSupport.ENTER_SESSION, doEnterNetSession);
		}
		
		protected function doEnterNetSession(e: ObjectEvent): void {
			Space.view.stage.removeEventListener(df_netSupport.ENTER_SESSION, doEnterNetSession);
			_timer.stop();
			
			_netSession = true;			
			if (!e.object.points[options.timerName]) createSession();
			else updatePoints(e.object.points[options.timerName]);
			Space.addEventListener(df_netSupport.NF_POINTSSTATE, doPointsState);
		}
		
		protected function createSession(): void {
			Space.dispatchEvent(new ObjectEvent(df_netSupport.SET_POINTSSTATE, {
				name		: options.timerName,
				interval	: options.period,
				map			: getMap()
			}));
		}
		
		protected function updateSession(): void {
			Space.dispatchEvent(new ObjectEvent(df_netSupport.UPDATE_POINTSSTATE, {
				name		: options.timerName,
				map			: getMap()
			}));
		}
		
		override protected function removeEvents():void {
			Space.view.stage.removeEventListener(df_netSupport.ENTER_SESSION, doEnterNetSession);
			Space.removeEventListener(df_netSupport.NF_POINTSSTATE, doPointsState);
			super.removeEvents();
		}
		
		protected function fillFreePoint(): void {
			if (points.length > 0) {
				var checkIndex: int = _curPoint;
				while (true) {
					if (isFreePoint(checkIndex)) {
						_curPoint = checkIndex;
						createPoint(_curPoint);
						break;
					}
					checkIndex = (checkIndex + 1) % points.length;
					if (checkIndex == _curPoint) break;
				}
			}
		}
		
		protected function doPointsState(e: ObjectEvent): void {
			if (e.object.name == options.timerName) {
				updatePoints(e.object.map);
			}
		}
		
		protected function doPeriod(e: TimerEvent): void {
			fillFreePoint();
		}
		
		override protected function doBeforeDisposeElem(element: df_element, pointIndex: int): void {
			if (_netSession) updateSession();
		}
		
		protected function isFreePoint(index: int): Boolean {
			return points[index].object == null;
		}
		
		protected function getMap(): Array {
			var result: Array = new Array();
			points.forEach(function(item: Object, i:int, arr: Array): void {
				result.push((item.object != null)?1:0);
			});
			return result;
		}
		
		protected function updatePoints(a_map: Array): void {
			_netSession = false;
			points.forEach(function(item: Object, i:int, arr: Array): void {
				if ((a_map[i] == 0) && (item.object != null)) item.object.pickUp();
				if ((a_map[i] == 1) && (item.object == null)) createPoint(i);
			});
			_netSession = true;
		}
		
		override public function dispose():void {
			_timer.removeEventListener(TimerEvent.TIMER, doPeriod);
			_netSession = false;
			points.forEach(function(item: Object, i:int, arr: Array): void {
				if (item.object != null) item.object.dispose();
			});
			super.dispose();
		}
	}
}